﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Threading.Tasks;
using System.Xml.Linq;
using CoreShop.Model;
using CoreShop.Repository;
using SqlSugar;
using static CoreShop.Library.GlobalEnumVars;


namespace CoreShop.Services
{
    /// <summary>
    /// 接口实现
    /// </summary>
    public class corecmsfoodcategoryServices : Repository<corecmsfoodcategory>, IcorecmsfoodcategoryServices
    {
        #region 实现重写增删改查操作==========================================================

        /// <summary>
        /// 重写异步插入方法
        /// </summary>
        /// <param name="entity">实体数据</param>
        /// <returns></returns>
        public bool InsertAsync(corecmsfoodcategory entity)
        {
            return base.Change<corecmsfoodcategory>().Insert(entity);
        }
        public bool InsertOrUpdate(List<corecmsfoodcategory> entity)
        {
            return base.InsertOrUpdate(entity);
        }
        /// <summary>
        /// 重写异步更新方法方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(corecmsfoodcategory entity)
        {
            return base.Change<corecmsfoodcategory>().Update(a => new corecmsfoodcategory()
            {
                corpId = entity.corpId,
                storeId = entity.storeId,
                parentId = entity.parentId,
                name = entity.name,
                byName = entity.byName,
                appletShow = entity.appletShow,
                helpCode = entity.helpCode,
                departId = entity.departId,
                upIcon = entity.upIcon,
                icon = entity.icon,
                modifyTime = entity.modifyTime
            }, a => a.id == entity.id);
        }

        /// <summary>
        /// 重写异步更新方法方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateAsync(List<corecmsfoodcategory> entity)
        {
            bool returnKey = true;
            foreach (var item in entity)
            {
                returnKey = base.Change<corecmsfoodcategory>().Update(a => new corecmsfoodcategory()
                {
                    corpId = item.corpId,
                    storeId = item.storeId,
                    parentId = item.parentId,
                    name = item.name,
                    byName = item.byName,
                    appletShow = item.appletShow,
                    helpCode = item.helpCode,
                    departId = item.departId,
                    upIcon = item.upIcon,
                    icon = item.icon,
                    modifyTime = item.modifyTime
                }, a => a.id == item.id);
            }
            return returnKey;
        }

        /// <summary>
        /// 重写删除指定ID的数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteByIdAsync(long id)
        {
            return base.Change<corecmsfoodcategory>().Update(a => new corecmsfoodcategory()
            {
                isDelete = true
            }, a => a.id == id);
        }

        /// <summary>
        /// 重写删除指定ID集合的数据(批量删除)
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public bool DeleteByIdsAsync(int[] ids)
        {
            bool returnKey = true;
            foreach (int id in ids)
            {
                returnKey = base.Change<corecmsfoodcategory>().Update(a => new corecmsfoodcategory()
                {
                    isDelete = true
                }, a => a.id == id);
            }
            return returnKey;
        }

        #endregion

        #region 获取缓存的所有数据==========================================================

        /// <summary>
        /// 获取缓存的所有数据
        /// </summary>
        /// <returns></returns>
        public List<corecmsfoodcategory> GetCaChe()
        {
            return base.GetList();
        }

        #endregion

        #region 根据条件查询分页数据
        /// <summary>
        /// 根据条件查询分页数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryPageAsync(ref int count, int? pageIndex, int? pageSize, string sName, corecmsstore store)
        {
            var storeorganization = new corecmsstoreorganization();
            var orgIds = new List<int>();
            var corpFoodTypeId = new List<long>();
            if (store.corpId > 0)
            {
                var orgStores = base.Change<corecmsstoreorganization>().AsQueryable().Where(p => p.isDelete == false && p.orgType == 0 && p.storeId == store.id).ToList();
                if (orgStores.Count > 0)
                {
                    orgIds = orgStores.Select(p => p.organizationId.Value).ToList();
                    //查询需要展示的总店共享商品分类
                    corpFoodTypeId = base.Change<corecmsfood>().AsQueryable().Where(p => p.storeId == store.corpId && orgStores.Select(o => o.organizationId).Contains(p.organizationId) && p.isDelete == false).Select(p => p.foodTypeId).ToList();
                }
            }

            List<corecmsfoodcategory> lst = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => a.storeId == store.id);

            if (corpFoodTypeId.Count > 0)
                where = where.Or(a => a.storeId == store.corpId && corpFoodTypeId.Contains(a.id));
            where = where.And(a => a.isDelete == false);

            if (!string.IsNullOrEmpty(sName))
            {
                where = where.And(a => a.name.Contains(sName) || a.name.Contains(sName) || a.byName.Contains(sName));
            }
            if (pageIndex >= 1 && pageSize > 0)
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression())
                    .ToPageList((int)pageIndex, (int)pageSize, ref count)
                    .OrderBy(a => a.sort).ToList();
            }
            else
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.sort).ToList();
            }

            return lst;
        }
        #endregion

        #region 根据条件查询分页数据
        /// <summary>
        /// 根据条件查询分页数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryChildAsync(ref int count, int foodTypeBindType, long parentId, int? pageIndex, int? pageSize)
        {
            var corpFoodTypeId = base.Change<corecmsfood>().AsQueryable()
                .Where(p => p.isDelete == false).Select(p => p.foodTypeId).Distinct().ToList();

            List<corecmsfoodcategory> lst = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => corpFoodTypeId.Contains(a.id));
            where = where.And(a => a.isDelete == false);
            if (parentId > 0)
            {
                //如果是上级分类和商品分类，直接a.parentId == parentId，否则关联多级，要处理parentId
                if (foodTypeBindType == (int)FoodTypeBindType.ParentAndChild)
                    where = where.And(a => a.parentId == parentId);
                else 
                {
                    var childIds = GetChildrenIds(parentId);
                    if (childIds == null) childIds = new List<long>();
                    childIds.Add(parentId);
                    where = where.And(a => childIds.Contains(a.id));
                }                
            }                

            if (pageIndex >= 1 && pageSize > 0)
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression())
                    .ToPageList((int)pageIndex, (int)pageSize, ref count)
                    .OrderBy(a => a.sort).ToList();
            }
            else
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.sort).ToList();
            }
            return lst;
        }
        #endregion

        #region 查询商品分类的大类
        /// <summary>
        /// 根据条件查询分页数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryParentAsync(ref int count,int foodTypeBindType, int? pageIndex, int? pageSize)
        {
            List<corecmsfoodcategory> lst = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();

            if (foodTypeBindType == (int)FoodTypeBindType.ParentAndChild)
            {
                var corpFoodTypeId = new corecmsfoodServices().AsQueryable()
                    .LeftJoin<corecmsfoodcategory>((f, t) => f.foodTypeId == t.id)
                    .Where((f, t) => f.isDelete == false).Select((f, t) => t.parentId).Distinct().ToList();

                where = where.And(a => corpFoodTypeId.Contains(a.id));
            }
            else
            {
                var foodTypeIds = new corecmsfoodServices().AsQueryable().Where(f => f.isDelete == false).Select(f => f.foodTypeId).Distinct().ToList();

                var categoryList = new List<corecmsfoodcategory>();
                foreach (var item in foodTypeIds)
                {
                    var parentData = QueryParentList(item);
                    if ((parentData != null) && (parentData.Count > 0))
                        categoryList.AddRange(parentData);
                }
                var topTypeIds = categoryList.Where(p=>p.parentId == 0).Select(p => p.id).Distinct().ToList();
                where = where.And(a => topTypeIds.Contains(a.id));
            }
               
            where = where.And(a => a.canPos == false);
            where = where.And(a => a.isDelete == false);

            if (pageIndex >= 1 && pageSize > 0)
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression())
                    .ToPageList((int)pageIndex, (int)pageSize, ref count)
                    .OrderBy(a => a.sort).ToList();
            }
            else
            {
                lst = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.sort).ToList();
            }
            return lst;
        }
        #endregion

        #region 根据条件查询分页数据
        /// <summary>
        /// 查询需要展示的总店商品分类
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryCorpFoodTypeId(corecmsstore store)
        {
            var where = Expressionable.Create<corecmsfoodcategory, corecmsfood>();
            where = where.And((c, f) => f.isDelete == false && c.corpId != c.tenantId);

            var typeIds = base.AsQueryable().LeftJoin<corecmsfood>((c, f) => c.id == f.foodTypeId)
                .WhereIF(true, where.ToExpression()).Select((c, f) => c.id).Distinct().ToList();

            if ((typeIds == null) || (typeIds.Count == 0)) return null;

            List<corecmsfoodcategory> list = new List<corecmsfoodcategory>();
            var where1 = Expressionable.Create<corecmsfoodcategory>();
            where1 = where1.And(a => a.corpId != a.tenantId && a.isDelete == false);
            list = base.AsQueryable().WhereIF(true, where1.ToExpression()).OrderBy(a => a.id).ToList();

            var categoryList = new List<corecmsfoodcategory>();
            foreach (var item in typeIds)
            {
                var parentData = QueryParentList(item); 
                if ((parentData != null) && (parentData.Count > 0))
                    categoryList.AddRange(parentData);
            }

            return categoryList;
        }
        #endregion


        #region 根据条件查询数据
        /// <summary>
        /// 根据条件查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryAsync(long corpId, string foodName)
        {
            //List<corecmsfood> foodTypeIdList = new corecmsfoodServices().AsQueryable().Where(p => p.name.Contains(foodName)).ToList();
            //var typeId = string.Join(",", foodTypeIdList.Select(it => it.foodTypeId).ToList());

            List<corecmsfoodcategory> list = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => a.isDelete == false && a.id > 0);
            if (corpId > 0)
            {
                where = where.And(a => a.corpId == corpId);
            }
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.id).ToList();
            return list;
        }
        #endregion
                
        #region 根据IDS查询数据
        /// <summary>
        /// 根据IDS查询数据
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryAsync(List<long> foodIds)
        {
            List<corecmsfoodcategory> list = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => foodIds.Contains(a.id));
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.id).ToList();
            return list;
        }

        /// <summary>
        /// 根据分类ID获取所有父类ID
        /// </summary>
        /// <returns></returns>
        public List<long> GetParentIds(long foodTypeId)
        {
            var list = QueryParentList(foodTypeId);
            return list.Select(p=>p.id).ToList();
        }

        /// <summary>
        /// 根据购物车所有商品父类ID
        /// </summary>
        /// <returns></returns>
        public List<OrderingGoodsTypeDto> GetOrderingGoodsTypes(List<corecmsfoodordering> orderings)
        {
            List<OrderingGoodsTypeDto> list = new List<OrderingGoodsTypeDto>();
            foreach (var ordering in orderings)
            {
                var sort = base.GetById(ordering.foodTypeId);
                if (sort != null) 
                {
                    list.Add(new OrderingGoodsTypeDto { foodTypeId = sort.id, orderingId = ordering.id });
                    long parentId = sort.parentId;
                    while (parentId > 0)
                    {
                        var sortParent = base.GetById(sort.parentId);
                        if (sortParent != null)
                        {
                            list.Add(new OrderingGoodsTypeDto { foodTypeId = sortParent.id, orderingId = ordering.id });
                            parentId = sortParent.parentId;
                        }
                        else
                            parentId = 0;
                        if (list.Count > 10) parentId = 0;//防止死循环
                    }
                }
            }            
            return list;
        }

        /// <summary>
        /// 根据分类ID获取所有父类ID
        /// </summary>
        /// <returns></returns>
        public List<long> GetChildrenIds(long foodTypeId)
        {
            List<corecmsfoodcategory> list = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => a.isDelete == false);
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).OrderBy(a => a.id).ToList();

            if (foodTypeId == 0) 
                return list.Select(p => p.id).ToList();

            var listChild = QueryChildAsync(foodTypeId);
            return listChild.Select(p => p.id).ToList();
        }
                
        /// <summary>
        /// 树型查询
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryTreeAsync()
        {
            List<corecmsfoodcategory> list = new List<corecmsfoodcategory>();
            var where = Expressionable.Create<corecmsfoodcategory>();
            where = where.And(a => a.departId == 1);
            list = base.AsQueryable().WhereIF(true, where.ToExpression()).ToTree(it => it.Child, it => it.parentId, 0);

            return list;
        }

        /// <summary>
        /// 查找所有下级
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryChildAsync(long parentId)
        {
            var list = base.AsQueryable().Where(p => p.isDelete == false).ToChildList(it => it.parentId, parentId);//parentId是主键，查主键为2下面所有
            return list;
        }

        /// <summary>
        /// 查询所有上级
        /// </summary>
        /// <param name="count"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sName"></param>
        /// <returns></returns>
        public List<corecmsfoodcategory> QueryParentList(long childId)
        {
            var list = base.AsQueryable().Where(p => p.isDelete == false).ToParentList(it => it.parentId, childId);
            return list;
        }

        #endregion
    }
}
